/**
 * @typedef {number[][]} Mat
 * @typedef {[x: number, y: number]} Coord
 * @typedef {[Coord, group: number[]]} M
 */
const mat = [
  [1, 1, 0, 0, 0],
  [1, 0, 1, 0, 0],
  [1, 0, 0, 0, 0],
  [1, 1, 0, 1, 1],
];
/**
 * @type {Set<Mat>[]}
 */
const dsu = [];

/**
 * @desc 将矩阵转化为邻接表
 * @param {Mat} mat
 * @returns {Coord[]}
 */
function toAdjacencyList(mat) {
  /**
   * @type {[number,number][]}
   */
  const res = [];
  for (let i = 0; i < mat.length; i++) {
    for (let j = 0; j < mat[i].length; j++) {
      if (mat[i][j]) {
        res.push([i, j]);
      }
    }
  }
  return res;
}

/**
 * @desc 查询是否在边界内
 * @param {Mat} mat
 * @param {Coord} coord
 * @param {number} sizeX
 * @param {number=} sizeY
 * @returns {Coord[]}
 */
function checkEdge(mat, coord, sizeX, sizeY) {
  // if (coord[0] > 0){
  //   if (coord[1] > 0){
  //     if (mat[coord[0] - 1][coord[1]] && mat[coord[0]][coord[1] - 1]){
  //       return true;
  //     }
  //   }
  // }
  const checkX = () => {
    /**
     * @type {[number | null, number | null]}
     */
    const resultX = [null, null];
    // 左溢出
    if (coord[0] > 0) {
      resultX[0] = coord[0] - 1;
    }
    // 右溢出
    if (coord[0] < sizeX - 1) {
      resultX[1] = coord[0] + 1;
    }
    return resultX;
  };
  const checkY = () => {
    /**
     * @type {[number | null, number | null]}
     */
    const resultY = [null, null];
    // 上溢出
    if (coord[1] > 0) {
      resultY[0] = coord[1] - 1;
    }
    // 下溢出
    if (coord[1] < (sizeY ?? sizeX) - 1) {
      resultY[1] = coord[1] + 1;
    }
    return resultY;
  };

  const edges = /**
   * @param {[number | null, number | null]} a
   * @param {[number | null, number | null]} b
   * @returns {[number, number][]}
   */ ((a, b) => {
    /**
     * @type {[number, number][]}
     */
    const result = [];
    for (let i = 0; i < 2; i++) {
      for (let j = 0; j < 2; j++) {
        if (a[i] !== null && b[j] !== null) {
          // eslint-disable-next-line no-warning-comments
          // @ts-ignore
          result.push([a[i], b[j]]);
        }
      }
    }
    return result;
  })(checkX(), checkY());
  return edges;
}

// const normalCase = checkEdge(mat, [1, 1], 3, 3);
// const normalCase2 = checkEdge(mat, [2, 1], 3, 3);

// for (let i = 0; i < 3; i++) {
//   for (let j = 0; j < 3; j++) {
//     console.log([i, j], checkEdge(mat, [i, j], 3, 3));
//   }
// }

// console.log(normalCase);
// console.log(normalCase2);

const AList = toAdjacencyList(mat);
// console.log(AList);

class DisjointSet {
  /**
   * @type {Record<number, number>}
   */
  reMap;

  constructor() {
    this.reMap = (() => {
      /**
       * @type {Record<number, number>}
       */
      const res = {};
      for (const [i, _] of Array.from({ length: AList.length }).entries()) {
        res[i] = i;
      }
      return res;
    })();
  }
}
